package com.demo.oauth2jFinalShiroServer.oauth2;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.demo.oauth2jFinalShiroServer.cache.OAuth2EntityCache;
import com.demo.oauth2jFinalShiroServer.common.CommonResult;
import com.demo.oauth2jFinalShiroServer.model.OAuth2Entity;
import com.google.gson.Gson;

public class ResourceAccessFilter extends FormAuthenticationFilter {
	
	private static final Logger logger = LoggerFactory.getLogger(ResourceAccessFilter.class);
	
	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
		String tokenStr = request.getParameter(OAuth.OAUTH_BEARER_TOKEN);
		if (!StringUtils.isEmpty(tokenStr) && OAuth2EntityCache.TOKEN_OAUTH2_MAP.containsKey(tokenStr)) {
    		OAuth2Entity entity = OAuth2EntityCache.TOKEN_OAUTH2_MAP.get(tokenStr);
    		if (entity != null && !entity.isTokenExpired()) {
    			try {
    				//使用access_token登录
					AuthenticationToken token = new ResourceAccessToken(tokenStr);
					Subject subject = getSubject(request, response);
					subject.login(token);
					//验证请求的资源是否在申请的scope范围内
					if (entity.getScopes().contains(((HttpServletRequest)request).getServletPath())) {
						return true;
					}
    			} catch (AuthenticationException e) {
    				logger.error(e.getMessage(), e);
    			}		
			}
    	}
    	CommonResult<String> commonResult = new CommonResult<>();
    	commonResult.setMsg("未授权");
    	response.setCharacterEncoding("UTF-8");
        response.getWriter().append(new Gson().toJson(commonResult)).flush();
        return false;    	
	}

}
